package com.summer.tools.common.utils;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.summer.tools.common.customize.CustomerEasyExcelStyle;
import com.summer.tools.common.enums.MimeEnum;
import org.apache.commons.compress.utils.CharsetNames;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.util.UriUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;


public class EasyExcelUtil {

    private static final Logger log = LoggerFactory.getLogger(EasyExcelUtil.class);

    private EasyExcelUtil() {}

    /**
     * 下载文件 - 不建议使用
     * 基于模板导出数据
     */
    public static void templateExport(List<?> dataList, String filePath, String fileName, HttpServletResponse response) {
        try(InputStream inputStream = ExcelUtil.class.getClassLoader().getResourceAsStream(filePath); OutputStream outputStream = response.getOutputStream()) {
            // 设置响应头
            response.setContentType(MimeEnum.EXCEL_2010.getContentType());
            response.setCharacterEncoding(CharsetNames.UTF_8);
            response.setHeader("Content-Disposition", "attachment; filename=" + UriUtils.encodePathSegment(fileName, CharsetNames.UTF_8));

            // 导出模板渲染
            ExcelWriter excelWriter = EasyExcelFactory.write(outputStream)
                    .excelType(ExcelTypeEnum.XLSX).withTemplate(inputStream).build();
            WriteSheet writeSheet = EasyExcelFactory.writerSheet().build();
            excelWriter.fill(dataList, writeSheet);
            excelWriter.finish();
        }catch (Exception e) {
            log.error("下载失败:", e);
        }
    }

    /**
     * 下载文件
     * 动态表头-单sheet
     */
    public static void customHeadExport(List<?> dataList, List<List<String>> head, String fileName, HttpServletResponse response){
        try(OutputStream outputStream = response.getOutputStream()){
            // 设置响应头
            response.setContentType(MimeEnum.EXCEL_2010.getContentType());
            response.setCharacterEncoding(CharsetNames.UTF_8);
            response.setHeader("Content-Disposition", "attachment; filename=" + UriUtils.encodePathSegment(fileName, CharsetNames.UTF_8));
            // 导出模板渲染
            ExcelWriter excelWriter = EasyExcelFactory.write(outputStream)
                    .excelType(ExcelTypeEnum.XLSX)
                    .head(head)
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
                    .autoCloseStream(Boolean.TRUE)
                    .build();
            WriteSheet writeSheet = EasyExcelFactory.writerSheet().build();
            excelWriter.write(dataList, writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            log.error("导出失败:", e);
        }
    }

    /**
     * 下载文件
     * 动态表头-多sheet
     */
    public static void customHeadExport(Map<String, List<?>> dataMap, Map<String, List<List<String>>> headMap, Map<String, List<Integer>> columnIndexMap, String fileName, HttpServletResponse response){
        try(OutputStream outputStream = response.getOutputStream()){
            // 设置响应头
            response.setContentType(MimeEnum.EXCEL_2010.getContentType());
            response.setCharacterEncoding(CharsetNames.UTF_8);
            response.setHeader("Content-Disposition", "attachment; filename=" + UriUtils.encodePathSegment(fileName, CharsetNames.UTF_8));
            // 导出模板渲染
            multiSheetExport(dataMap, headMap, columnIndexMap, outputStream);
        } catch (Exception e) {
            log.error("导出失败:", e);
        }
    }

    /**
     * 下载文件
     */
    public static void export(List<?> dataList, Class<?> headClass, String fileName, HttpServletResponse response) {
        try(OutputStream outputStream = response.getOutputStream()) {
            // 设置响应头
            response.setContentType(MimeEnum.EXCEL_2010.getContentType());
            response.setCharacterEncoding(CharsetNames.UTF_8);
            response.setHeader("Content-Disposition", "attachment; filename=" + UriUtils.encodePathSegment(fileName, CharsetNames.UTF_8));

            // 导出模板渲染
            ExcelWriter excelWriter = EasyExcelFactory.write(outputStream)
                    .excelType(ExcelTypeEnum.XLSX).head(headClass).build();
            WriteSheet writeSheet = EasyExcelFactory.writerSheet().build();
            excelWriter.write(dataList, writeSheet);
            excelWriter.finish();
        }catch (Exception e) {
            log.error("导出失败:", e);
        }
    }

    /**
     * 导出到文件
     */
    public static void export(List<?> dataList, Class<?> headClass, File file) {
        try(OutputStream outputStream = new FileOutputStream(file)) {

            // 导出模板渲染
            ExcelWriter excelWriter = EasyExcelFactory.write(outputStream)
                    .excelType(ExcelTypeEnum.XLSX).head(headClass).build();
            WriteSheet writeSheet = EasyExcelFactory.writerSheet().build();
            excelWriter.write(dataList, writeSheet);
            excelWriter.finish();
        }catch (Exception e) {
            log.error("导出失败:", e);
        }
    }

    /**
     * 导出到文件
     * 动态表头-多sheet
     */
    public static void customHeadExport(Map<String, List<?>> dataMap, Map<String, List<List<String>>> headMap, Map<String, List<Integer>> columnIndexMap, File file){
        try(OutputStream outputStream = new FileOutputStream(file)){
            multiSheetExport(dataMap, headMap, columnIndexMap, outputStream);
        } catch (Exception e) {
            log.error("导出失败:", e);
        }
    }

    private static void multiSheetExport(Map<String, List<?>> dataMap, Map<String, List<List<String>>> headMap, Map<String, List<Integer>> columnIndexMap, OutputStream outputStream) {
        // 导出模板渲染
        ExcelWriter excelWriter = EasyExcelFactory.write(outputStream)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .excelType(ExcelTypeEnum.XLSX)
                .autoCloseStream(Boolean.TRUE)
                .build();

        AtomicInteger sheetNo = new AtomicInteger(0);
        headMap.forEach((sheetName, head) -> {
            WriteSheet writeSheet = EasyExcelFactory.writerSheet(sheetNo.get(), sheetName).registerWriteHandler(new CustomerEasyExcelStyle(columnIndexMap.get(sheetName))).build();
            WriteTable writeTable = EasyExcelFactory.writerTable(0).head(head).needHead(true).build();
            excelWriter.write(dataMap.get(sheetName), writeSheet, writeTable);

            sheetNo.getAndIncrement();
        });
        excelWriter.finish();
    }
}
